﻿using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using GSQ.BusinessEntities;
using GSQ.DataAccess.DataSetTableAdapters;

namespace GSQ.DataAccess
{
    public class FacturasDA
    {
        private void InicializarAdaptadores()
        {
            this.cnn = new SqlConnection(Connection.GetConnectionString);
            cnn.Open();
            this.tr = cnn.BeginTransaction();

            AdapterMaster.Connection = cnn;
            AdapterMaster.Transaction = tr;

            AdapterDetaill.Connection = cnn;
            AdapterDetaill.Transaction = tr;

            vAdapterMaster.Connection = cnn;
            vAdapterMaster.Transaction = tr;

            vAdapterDetaill.Connection = cnn;
            vAdapterDetaill.Transaction = tr;

            AdapterSecuencias.Connection = cnn;
            AdapterSecuencias.Transaction = tr;

            AdapterProductos.Connection = cnn;
            AdapterProductos.Transaction = tr;

            AdapterNcf.Connection = cnn;
            AdapterNcf.Transaction = tr;

            AdapterFacturasPagos.Connection = cnn;
            AdapterFacturasPagos.Transaction = tr;

            AdapterCotizaciones.Connection = cnn;
            AdapterCotizaciones.Transaction = tr;

            AdapterUtilidades.Connection = cnn;
            AdapterUtilidades.Transaction = tr;

            AdapterClientes.Connection = cnn;
            AdapterClientes.Transaction = tr;

            AdapterNC.Connection = cnn;
            AdapterNC.Transaction = tr;
        }

        #region Variables

        #region TableAdapters
        private FACTURASTableAdapter AdapterMaster = new FACTURASTableAdapter();
        private FACTURAS_DETALLESTableAdapter AdapterDetaill = new FACTURAS_DETALLESTableAdapter();
        private V_FACTURASTableAdapter vAdapterMaster = new V_FACTURASTableAdapter();
        private V_FACTURAS_DETALLESTableAdapter vAdapterDetaill = new V_FACTURAS_DETALLESTableAdapter();
        private SECUENCIASTableAdapter AdapterSecuencias = new SECUENCIASTableAdapter();
        private PRODUCTOSTableAdapter AdapterProductos = new PRODUCTOSTableAdapter();
        private NCFTableAdapter AdapterNcf = new NCFTableAdapter();
        private FACTURAS_PAGOSTableAdapter AdapterFacturasPagos = new FACTURAS_PAGOSTableAdapter();
        private COTIZACIONESTableAdapter AdapterCotizaciones = new COTIZACIONESTableAdapter();
        private UTILIDADESTableAdapter AdapterUtilidades = new UTILIDADESTableAdapter();
        private CLIENTESTableAdapter AdapterClientes = new CLIENTESTableAdapter();
        private NCTableAdapter AdapterNC = new NCTableAdapter();
        #endregion

        private DataSet.FACTURASDataTable entitiesMaster;
        private DataSet.FACTURAS_DETALLESDataTable entitiesDetaill;
        private DataSet.SECUENCIASRow entitySecuencia;
        private DataSet.NCFRow entityNcf;
        private DataSet.FACTURASRow entityMaster;
        private DataSet.FACTURAS_DETALLESRow entityDetaill;
        private DataSet.FACTURAS_PAGOSDataTable entitiesFacturasPagos;
        private SqlConnection cnn = null;
        private SqlTransaction tr = null;
        #endregion

        public decimal Insert(FACTURAS value)
        {
            bool InternalOpen = false;
            try
            {
                #region Inicializar Metodo
                if (this.cnn == null)
                {
                    InternalOpen = true;
                    InicializarAdaptadores();
                }
                #endregion

                #region Obtener y Ajustar secuencias

                this.entityNcf = this.AdapterNcf.GetDataByID(value.ID_NCF).FirstOrDefault();//Obtener valores de secuencias NCF
                this.AdapterNcf.NcfUpdateValueCommnadByID(value.ID_NCF);//Actualizar valores secuencias NCF


                if (value.ID_NCF == 1)//Buscar y ajustar valores de secuencias
                {
                    this.entitySecuencia = this.AdapterSecuencias.GetDataByID(9).FirstOrDefault();
                    this.AdapterSecuencias.SecuenciasUpdateCommand(9);
                }
                else
                {
                    if (entityNcf.VALUE >= entityNcf.HASTA)//Validar Disponibilidad de NCF
                    {
                        if (value.FACTURAS_PAGOS != null && value.FACTURAS_PAGOS.Count > 0)
                            for (int I = value.FACTURAS_PAGOS.Count - 1; I == 0; I--)
                            {
                                if (value.FACTURAS_PAGOS[I].ID == 0)
                                    value.FACTURAS_PAGOS.RemoveAt(I);
                            }
                        value.M_PAGADO = 0;
                        throw new Exception(string.Format("No es posible generar está factura con este <<TIPO DE NCF>>  ya que no quedan secuencias de NCF disponibles{0}{0}Informe a contabilidad para que la soliciten a DGII", Environment.NewLine));
                    }
                    if (value.ID_CONDICION == 1)//Si la factura es de credito
                    {
                        this.entitySecuencia = this.AdapterSecuencias.GetDataByID(2).FirstOrDefault();//Buscar la secuencia para facturas de credito donde su ID = 2 
                        this.AdapterSecuencias.SecuenciasUpdateCommand(2);//Actualizar valor de secuencia
                    }
                    else
                    {
                        this.entitySecuencia = this.AdapterSecuencias.GetDataByID(3).FirstOrDefault();//Buscar la secuencia para facturas de contado donde su ID = 3
                        this.AdapterSecuencias.SecuenciasUpdateCommand(3);//Actualizar valor de secuencia
                    }
                }
                #endregion

                #region Preparar Encabezado
                entitiesMaster = new DataSet.FACTURASDataTable(); // Inicializo la tabla principal 
                entityMaster = entitiesMaster.NewFACTURASRow(); // Inicializo la fila principal apartir de la tabla principal

                entityMaster.ID = 0;
                entityMaster.ID_CONDICION = value.ID_CONDICION;
                entityMaster.ID_NCF = value.ID_NCF;
                entityMaster.ID_CLIENTE = value.ID_CLIENTE;
                entityMaster.ID_VENDEDOR = value.ID_VENDEDOR;
                entityMaster.ID_USUARIO = value.ID_USUARIO;
                entityMaster.NRO_FACTURA = entitySecuencia.VALUE + 1;// Asigno el valor de secuencia mas 1
                entityMaster.SEQ_NCF = entityNcf.VALUE + 1;
                entityMaster.FECHA_HORA = value.FECHA_HORA;
                entityMaster.FECHA_VENCIMIENTO = value.FECHA_VENCIMIENTO;
                if (value.ID_COTIZACIONES != null && value.ID_COTIZACIONES != string.Empty)
                    entityMaster.COTIZACIONES = value.ID_COTIZACIONES;
                if (value.ORDEN_COMPRA != null && value.ORDEN_COMPRA != string.Empty)
                    entityMaster.ORDEN_COMPRA = value.ORDEN_COMPRA;
                entityMaster.ACTIVO = value.ACTIVO;
                if (value.OBSERVACIONES != null && value.OBSERVACIONES != string.Empty)
                    entityMaster.OBSERVACIONES = value.OBSERVACIONES;
                entityMaster.M_TOTAL = value.M_TOTAL;
                if (this.entityNcf.IMPUESTOS)
                    entityMaster.T_IMPUESTO = value.T_IMPUESTO;
                else
                    entityMaster.T_IMPUESTO = 0;
                entityMaster.T_DESCUENTO = value.T_DESCUENTO;
                entityMaster.M_PAGADO = 0;

                entitiesMaster.AddFACTURASRow(entityMaster); //Agrego la fila principal a la tabla principal 
                this.AdapterMaster.Update(this.entitiesMaster);
                value.ID = entityMaster.ID;
                #endregion

                #region Cotizaciones
                //Actualizando tabla cotizaciones si fue seleccionada
                if (value.ID_COTIZACIONES != null && value.ID_COTIZACIONES != string.Empty)
                {
                    DataSet.COTIZACIONESRow rwCotizaciones = AdapterCotizaciones.GetDataByID(decimal.Parse(value.ID_COTIZACIONES)).FirstOrDefault();
                    rwCotizaciones.ACTIVO = false;
                    AdapterCotizaciones.Update(rwCotizaciones);
                }
                #endregion

                #region Ajustar Montos de Clientes
                if (value.ID_CONDICION == 1)
                {
                    DataSet.CLIENTESRow rwCliente = AdapterClientes.GetDataByID(value.ID_CLIENTE).FirstOrDefault();
                    rwCliente.MONTO_ADEUDADO += value.M_TOTAL;
                    AdapterClientes.Update(rwCliente);
                }
                #endregion

                #region Preparar Detalle

                entitiesDetaill = new DataSet.FACTURAS_DETALLESDataTable();
                foreach (FACTURAS_DETALLES rw in value.FACTURAS_DETALLES)
                {
                    entityDetaill = entitiesDetaill.NewFACTURAS_DETALLESRow();

                    AdapterProductos.ProductosUpdateExistencia(rw.CANTIDAD * -1, rw.ID_PRODUCTO);//Ajustar stock de productos

                    entityDetaill.ID = entityMaster.ID;
                    entityDetaill.ID_PRODUCTO = rw.ID_PRODUCTO;
                    entityDetaill.CANTIDAD = rw.CANTIDAD;
                    entityDetaill.COSTO = rw.COSTO;
                    entityDetaill.PRECIO = rw.PRECIO;
                    entityDetaill.DESCUENTO = rw.DESCUENTO;
                    entityDetaill.X_DESCUENTO = rw.X_DESCUENTO;
                    if (entityNcf.IMPUESTOS)// Determinando si por el tipo  de ncf se agregan los impuestos
                    {
                        entityDetaill.IMPUESTO = rw.IMPUESTO;
                        entityDetaill.X_IMPUESTO = rw.X_IMPUESTO;
                    }
                    else
                    {
                        entityDetaill.IMPUESTO = 0;
                        entityDetaill.X_IMPUESTO = 0;
                    }
                    entityDetaill.C_DEVUELTA = rw.C_DEVUELTA;
                    entitiesDetaill.AddFACTURAS_DETALLESRow(entityDetaill);
                }
                this.AdapterDetaill.Update(this.entitiesDetaill);
                #endregion

                this.tr.Commit();
            }
            catch
            {
                if (InternalOpen)
                    tr.Rollback();
                if (value.FACTURAS_PAGOS != null && value.FACTURAS_PAGOS.Count > 0)
                    for (int I = value.FACTURAS_PAGOS.Count - 1; I == 0; I--)
                    {
                        if (value.FACTURAS_PAGOS[I].ID == 0)
                            value.FACTURAS_PAGOS.RemoveAt(I);
                    }
                value.M_PAGADO = 0;
                throw;
            }
            finally
            {
                if (InternalOpen && this.cnn.State != System.Data.ConnectionState.Closed)
                    this.cnn.Close();
            }
            return value.ID;
        }

        //public decimal InsertOld(FACTURAS value)
        //{
        //    using (SqlConnection cnn = new SqlConnection(Connection.GetConnectionString))
        //    {
        //        try
        //        {
        //            #region Inicializadores
        //            cnn.Open(); // abro la conexion
        //            AdapterMaster.Connection = cnn; // asignar la conexion al tableAdapter principal

        //            SqlTransaction tr = cnn.BeginTransaction(); // Creo la transaccion y la inicializo con la conexion
        //            AdapterMaster.Transaction = tr; // Asigno  la transaccion al tableAdapter principal

        //            AdapterSecuencias.Connection = cnn; // Asigno la conexion a tableAdapter que maneja las secuencias
        //            AdapterSecuencias.Transaction = tr; // Asigno la transaccion tableAdapter que maneja las secuencias

        //            AdapterNcf.Connection = cnn;
        //            AdapterNcf.Transaction = tr;
        //            #endregion

        //            entityNcf = AdapterNcf.GetDataByID(value.ID_NCF).FirstOrDefault();

        //            #region Valores de secuencias
        //            if (value.ID_CONDICION == 1)// Obtengo el valor de secuencia en su tabla correspondiente y actualizo el monto de pago de cliente
        //            {
        //                CLIENTESTableAdapter adapterCliente = new CLIENTESTableAdapter { Connection = cnn, Transaction = tr };
        //                DataSet.CLIENTESRow rwCliente = adapterCliente.GetDataByID(value.ID_CLIENTE).FirstOrDefault();
        //                rwCliente.MONTO_ADEUDADO += value.M_TOTAL;
        //                adapterCliente.Update(rwCliente);

        //                if (value.ID_NCF != 1)
        //                    entitySecuencia = AdapterSecuencias.GetDataByID(2).FirstOrDefault();
        //                else
        //                    entitySecuencia = AdapterSecuencias.GetDataByID(9).FirstOrDefault();
        //            }
        //            else
        //            {
        //                if (value.ID_NCF != 1)
        //                    entitySecuencia = AdapterSecuencias.GetDataByID(3).FirstOrDefault();
        //                else
        //                    entitySecuencia = AdapterSecuencias.GetDataByID(9).FirstOrDefault();
        //            }
        //            #endregion

        //            #region Validar valores de NCF
        //            //Validar valores de ncf
        //            if (value.ID_NCF != 1)
        //                if (entityNcf.VALUE >= entityNcf.HASTA)
        //                {
        //                    for (int I = value.FACTURAS_PAGOS.Count - 1; I == 0; I--)
        //                    {
        //                        if (value.FACTURAS_PAGOS[I].ID == 0)
        //                            value.FACTURAS_PAGOS.RemoveAt(I);
        //                    }
        //                    throw new Exception(string.Format("No es posible generar está factura con este <<TIPO DE NCF>> ya que no quedan secuencias para facturar{0}{0}Informe a contabilidad para que la soliciten a DGII", Environment.NewLine));
        //                }
        //            #endregion

        //            #region Preparar Encabezado
        //            entitiesMaster = new DataSet.FACTURASDataTable(); // Inicializo la tabla principal 
        //            entityMaster = entitiesMaster.NewFACTURASRow(); // Inicializo la fila principal apartir de la tabla principal


        //            entityMaster.ID = 0;
        //            entityMaster.ID_CONDICION = value.ID_CONDICION;
        //            entityMaster.ID_NCF = value.ID_NCF;
        //            entityMaster.ID_CLIENTE = value.ID_CLIENTE;
        //            entityMaster.ID_VENDEDOR = value.ID_VENDEDOR;
        //            entityMaster.ID_USUARIO = value.ID_USUARIO;
        //            entityMaster.NRO_FACTURA = entitySecuencia.VALUE + 1;// Asigno el valor de secuencia mas 1
        //            entityMaster.SEQ_NCF = entityNcf.VALUE + 1;
        //            entityMaster.FECHA_HORA = value.FECHA_HORA;
        //            entityMaster.FECHA_VENCIMIENTO = value.FECHA_VENCIMIENTO;
        //            if (value.ID_COTIZACIONES != null && value.ID_COTIZACIONES != string.Empty)
        //                entityMaster.COTIZACIONES = value.ID_COTIZACIONES;
        //            if (value.ORDEN_COMPRA != null && value.ORDEN_COMPRA != string.Empty)
        //                entityMaster.ORDEN_COMPRA = value.ORDEN_COMPRA;
        //            entityMaster.ACTIVO = value.ACTIVO;
        //            if (value.OBSERVACIONES != null && value.OBSERVACIONES != string.Empty)
        //                entityMaster.OBSERVACIONES = value.OBSERVACIONES;
        //            entityMaster.T_IMPUESTO = value.T_IMPUESTO;
        //            entityMaster.T_DESCUENTO = value.T_DESCUENTO;
        //            entityMaster.M_TOTAL = value.M_TOTAL;
        //            entityMaster.M_PAGADO = value.M_PAGADO;

        //            entitiesMaster.AddFACTURASRow(entityMaster); //Agrego la fila principal a la tabla principal 
        //            #endregion

        //            try
        //            {
        //                AdapterMaster.Update(entitiesMaster); // Ejecuto la operacion de update para insertar el encabezado 

        //                if (value.ID_NCF != 1)
        //                    if (value.ID_CONDICION == 1)// Ejecuto la operacion para actualizar la secuencia 
        //                        AdapterSecuencias.SecuenciasUpdateCommand(2);
        //                    else
        //                        AdapterSecuencias.SecuenciasUpdateCommand(3);
        //                else
        //                    AdapterSecuencias.SecuenciasUpdateCommand(9);

        //                AdapterNcf.NcfUpdateValueCommnadByID(value.ID_NCF); // Ejecuto la operacion para actualizar la secuencia de ncf

        //                #region Preparar Detalle
        //                AdapterDetaill.Connection = cnn; // Asigno la conexion al tableAdapter de detalle 
        //                AdapterDetaill.Transaction = tr; // Asigno la transaccion al tableAdapter de detalle                     

        //                AdapterProductos.Connection = cnn;
        //                AdapterProductos.Transaction = tr;

        //                entitiesDetaill = new DataSet.FACTURAS_DETALLESDataTable();
        //                foreach (FACTURAS_DETALLES rw in value.FACTURAS_DETALLES)
        //                {
        //                    entityDetaill = entitiesDetaill.NewFACTURAS_DETALLESRow();

        //                    AdapterProductos.ProductosUpdateExistencia(rw.CANTIDAD, rw.ID_PRODUCTO);


        //                    entityDetaill.ID = entityMaster.ID;
        //                    entityDetaill.ID_PRODUCTO = rw.ID_PRODUCTO;
        //                    entityDetaill.CANTIDAD = rw.CANTIDAD;
        //                    entityDetaill.COSTO = rw.COSTO;
        //                    entityDetaill.PRECIO = rw.PRECIO;
        //                    entityDetaill.DESCUENTO = rw.DESCUENTO;
        //                    entityDetaill.X_DESCUENTO = rw.X_DESCUENTO;
        //                    if (entityNcf.IMPUESTOS)// Determinando si por el tipo  de ncf hay que dar de descuento el % de descuento
        //                    {

        //                    }
        //                    else
        //                    {
        //                        entityDetaill.DESCUENTO = rw.DESCUENTO + rw.IMPUESTO;
        //                        entityDetaill.X_DESCUENTO = rw.X_DESCUENTO + rw.X_IMPUESTO;
        //                    }
        //                    entityDetaill.IMPUESTO = rw.IMPUESTO;
        //                    entityDetaill.X_IMPUESTO = rw.X_IMPUESTO;
        //                    entityDetaill.C_DEVUELTA = rw.C_DEVUELTA;
        //                    entitiesDetaill.AddFACTURAS_DETALLESRow(entityDetaill);
        //                }
        //                AdapterDetaill.Update(entitiesDetaill);
        //                #endregion

        //                #region Pagos

        //                //Insertar los pagos y ajustar montos pagados de la factura
        //                DataSet.UTILIDADESRow utilidadesRW = new DataSetTableAdapters.UTILIDADESTableAdapter { Connection = cnn, Transaction = tr }.GetData().FirstOrDefault();
        //                if (utilidadesRW.COBRAR_FACTURAS_AL_GUARDAR)
        //                {
        //                    decimal montoPagado = 0;
        //                    if (value.FACTURAS_PAGOS.Count > 0)
        //                    {
        //                        DataSetTableAdapters.FACTURAS_PAGOSTableAdapter pagosAdap = new FACTURAS_PAGOSTableAdapter() { Connection = cnn, Transaction = tr };
        //                        DataSet.FACTURAS_PAGOSDataTable PagosTD = new DataSet.FACTURAS_PAGOSDataTable();

        //                        foreach (FACTURAS_PAGOS rw in value.FACTURAS_PAGOS)
        //                        {
        //                            montoPagado = montoPagado + rw.MONTO;
        //                            DataSet.FACTURAS_PAGOSRow rwPagos = PagosTD.NewFACTURAS_PAGOSRow();
        //                            rwPagos.ID_FACTURA = entityMaster.ID;
        //                            rwPagos.ID_TIPO = rw.ID_TIPO;
        //                            if (rw.ID_BANCO != null && rw.ID_BANCO != 0)
        //                                rwPagos.ID_BANCO = (decimal)rw.ID_BANCO;
        //                            rwPagos.ID_USUARIO = rw.ID_USUARIO;
        //                            if (rw.NRO_DOCUMENTO != string.Empty)
        //                                rwPagos.NRO_DOCUMENTO = rw.NRO_DOCUMENTO;
        //                            if (rw.PORTADOR != string.Empty)
        //                                rwPagos.PORTADOR = rw.PORTADOR;
        //                            if (rw.TELEFONO != string.Empty)
        //                                rwPagos.TELEFONO = rw.TELEFONO;
        //                            rwPagos.FECHA = rw.FECHA;
        //                            rwPagos.MONTO = rw.MONTO;
        //                            PagosTD.AddFACTURAS_PAGOSRow(rwPagos);
        //                        }
        //                        pagosAdap.Update(PagosTD);
        //                        entityMaster.M_PAGADO = montoPagado;
        //                        AdapterMaster.Update(entityMaster);
        //                    }
        //                }
        //                #endregion

        //                #region Cotizaciones
        //                //Actualizando tabla cotizaciones si fue seleccionada
        //                if (value.ID_COTIZACIONES != null && value.ID_COTIZACIONES != string.Empty)
        //                {
        //                    DataSetTableAdapters.COTIZACIONESTableAdapter adapterCotizaciones = new COTIZACIONESTableAdapter();
        //                    adapterCotizaciones.Connection = cnn;
        //                    adapterCotizaciones.Transaction = tr;
        //                    DataSet.COTIZACIONESRow rwCotizaciones = adapterCotizaciones.GetDataByID(decimal.Parse(value.ID_COTIZACIONES)).FirstOrDefault();
        //                    rwCotizaciones.ACTIVO = false;
        //                    adapterCotizaciones.Update(rwCotizaciones);
        //                }
        //                #endregion

        //                tr.Commit();
        //            }
        //            catch (Exception ex)
        //            {
        //                tr.Rollback();
        //                throw ex;
        //            }

        //            value.ID = entityMaster.ID;
        //            return value.ID;
        //        }
        //        finally
        //        {
        //            if (cnn.State != System.Data.ConnectionState.Closed)
        //                cnn.Close();
        //        }
        //    }
        //}

        public decimal Update(FACTURAS newValue, FACTURAS oldValue)
        {
            throw new NotImplementedException();
            //using (SqlConnection cnn = new SqlConnection(Connection.GetConnectionString))
            //{
            //    try
            //    {
            //        cnn.Open(); // abro la conexion
            //        AdapterMaster.Connection = cnn; // asignar la conexion al tableAdapter principal

            //        SqlTransaction tr = cnn.BeginTransaction(); // Creo la transaccion y la inicializo con la conexion
            //        AdapterMaster.Transaction = tr; // Asigno  la transaccion al tableAdapter principal

            //        entitiesMaster = this.AdapterMaster.GetDataByID(oldValue.ID);
            //        entityMaster = this.entitiesMaster.FirstOrDefault(); // Inicializo la fila principal apartir de la tabla principal

            //        entityMaster.ID_CONDICION = newValue.ID_CONDICION;
            //        entityMaster.TIPO = newValue.TIPO;
            //        entityMaster.ID_USUARIO = newValue.ID_USUARIO;
            //        entityMaster.FECHA = newValue.FECHA;
            //        entityMaster.F_VENCIMIENTO = newValue.F_VENCIMIENTO;
            //        entityMaster.ID_SUPLIDOR = newValue.ID_SUPLIDOR;
            //        entityMaster.NRO_FACTURA = newValue.NRO_FACTURA;
            //        if (newValue.NCF != null && newValue.NCF != string.Empty)
            //            entityMaster.NCF = newValue.NCF;
            //        if (newValue.OBSERVACIONES != null && newValue.OBSERVACIONES != string.Empty)
            //            entityMaster.OBSERVACIONES = newValue.OBSERVACIONES;
            //        entityMaster.ACTIVO = newValue.ACTIVO;

            //        try
            //        {
            //            AdapterMaster.Update(entitiesMaster); // Ejecuto la operacion de update para insertar el encabezado 

            //            AdapterDetaill.Connection = cnn; // Asigno la conexion al tableAdapter de detalle 
            //            AdapterDetaill.Transaction = tr; // Asigno la transaccion al tableAdapter de detalle                        

            //            DataSet.UTILIDADESRow utilidades = new DataSetTableAdapters.UTILIDADESTableAdapter { Connection = cnn, Transaction = tr }.GetData().FirstOrDefault();

            //            AdapterProductos.Connection = cnn;
            //            AdapterProductos.Transaction = tr;


            //            DataSet.COMPRAS_DETALLESDataTable comprasDetalles = AdapterDetaill.GetDataByID(oldValue.ID);
            //            foreach (DataSet.COMPRAS_DETALLESRow r in comprasDetalles)
            //            {
            //                AdapterProductos.ProductosUpdateExistencia((r.CANTIDAD * -1), r.ID_PRODUCTO);
            //            }
            //            AdapterDetaill.DeleteByID(oldValue.ID);
            //            entitiesDetaill = new DataSet.COMPRAS_DETALLESDataTable();

            //            foreach (COMPRAS_DETALLES rw in newValue.COMPRAS_DETALLES)
            //            {
            //                entityDetaill = entitiesDetaill.NewCOMPRAS_DETALLESRow();
            //                AdapterProductos.ProductosUpdateExistencia(rw.CANTIDAD, rw.ID_PRODUCTO);
            //                DataSet.PRODUCTOSRow producto = AdapterProductos.GetDataByID(rw.ID_PRODUCTO).FirstOrDefault();
            //                entityDetaill.COSTO_ANTERIOR = producto.COSTO;
            //                entityDetaill.PRECIO_ANTERIOR = producto.PRECIO;
            //                if (utilidades.AJUSTAR_PRECIOS_COSTO_COMPRAS)
            //                {
            //                    producto.COSTO = rw.COSTO;
            //                    producto.PRECIO = rw.COSTO + ((rw.COSTO * producto.X_GANANCIA) / 100);
            //                    AdapterProductos.Update(producto);
            //                }



            //                entityDetaill.ID = entityMaster.ID;
            //                entityDetaill.ID_PRODUCTO = rw.ID_PRODUCTO;
            //                entityDetaill.CANTIDAD = rw.CANTIDAD;
            //                entityDetaill.COSTO = rw.COSTO;
            //                entityDetaill.PRECIO = rw.PRECIO;
            //                entityDetaill.DESCUENTO = rw.DESCUENTO;
            //                entityDetaill.X_DESCUENTO = rw.X_DESCUENTO;
            //                entityDetaill.IMPUESTO = rw.IMPUESTO;
            //                entityDetaill.X_IMPUESTO = rw.X_IMPUESTO;
            //                entityDetaill.C_DEVUELTA = rw.C_DEVUELTA;
            //                entitiesDetaill.AddCOMPRAS_DETALLESRow(entityDetaill);
            //            }
            //            AdapterDetaill.Update(entitiesDetaill);
            //            tr.Commit();
            //        }
            //        catch (Exception ex)
            //        {
            //            tr.Rollback();
            //            throw ex;
            //        }

            //        newValue.ID = entityMaster.ID;
            //        return newValue.ID;
            //    }
            //    finally
            //    {
            //        if (cnn.State != System.Data.ConnectionState.Closed)
            //            cnn.Close();
            //    }
            //}
        }

        public FACTURAS GetById(decimal id)
        {
            bool InternalOpen = false;
            try
            {
                #region Inicializar Metodo
                if (this.cnn == null)
                {
                    InternalOpen = true;
                    InicializarAdaptadores();
                }
                #endregion

                DataSet.V_FACTURASRow rw = this.vAdapterMaster.GetDataByID(id).FirstOrDefault();
                FACTURAS factura = null;
                if (rw != null)
                {
                    factura = GetEntity(rw, vAdapterDetaill.GetDataByID(rw.ID));
                }
                return factura;
            }
            finally
            {
                if (InternalOpen && this.cnn.State != System.Data.ConnectionState.Closed)
                    this.cnn.Close();
            }
        }

        public List<FACTURAS> GetAll()
        {
            bool InternalOpen = false;
            try
            {
                #region Inicializar Metodo
                if (this.cnn == null)
                {
                    InternalOpen = true;
                    InicializarAdaptadores();
                }
                #endregion

                List<FACTURAS> list = new List<FACTURAS>();
                foreach (DataSet.V_FACTURASRow rw in vAdapterMaster.GetData())
                {
                    list.Add(GetEntity(rw, null));
                }
                return list;
            }
            finally
            {
                if (InternalOpen && this.cnn.State != System.Data.ConnectionState.Closed)
                    this.cnn.Close();
            }
        }

        public List<FACTURAS> GetByFechas(DateTime value1, DateTime value2)
        {

            bool InternalOpen = false;
            try
            {
                #region Inicializar Metodo
                if (this.cnn == null)
                {
                    InternalOpen = true;
                    InicializarAdaptadores();
                }
                #endregion
                List<FACTURAS> list = new List<FACTURAS>();
                foreach (DataSet.V_FACTURASRow rw in vAdapterMaster.GetDataByFechas(value1.Date, value2.Date))
                {
                    list.Add(GetEntity(rw, null));
                }
                return list;
            }
            finally
            {
                if (InternalOpen && this.cnn.State != System.Data.ConnectionState.Closed)
                    this.cnn.Close();
            }
        }

        public List<FACTURAS> GetByCliente(decimal id)
        {
            bool InternalOpen = false;
            try
            {
                #region Inicializar Metodo
                if (this.cnn == null)
                {
                    InternalOpen = true;
                    InicializarAdaptadores();
                }
                #endregion
                List<FACTURAS> list = new List<FACTURAS>();
                foreach (DataSet.V_FACTURASRow rw in vAdapterMaster.GetDataByIdCliente(id))
                {
                    list.Add(GetEntity(rw, null));
                }
                return list;
            }
            finally
            {
                if (InternalOpen && this.cnn.State != System.Data.ConnectionState.Closed)
                    this.cnn.Close();
            }
        }

        public List<FACTURAS> GetByCliente(string value)
        {
            bool InternalOpen = false;
            try
            {
                #region Inicializar Metodo
                if (this.cnn == null)
                {
                    InternalOpen = true;
                    InicializarAdaptadores();
                }
                #endregion
                List<FACTURAS> list = new List<FACTURAS>();
                foreach (DataSet.V_FACTURASRow rw in vAdapterMaster.GetDataByCliente(value.Trim()))
                {
                    list.Add(GetEntity(rw, null));
                }
                return list;
            }
            finally
            {
                if (InternalOpen && this.cnn.State != System.Data.ConnectionState.Closed)
                    this.cnn.Close();
            }
        }

        public List<FACTURAS> GetByNroFactura(decimal nroFactura)
        {
            bool InternalOpen = false;
            try
            {
                #region Inicializar Metodo
                if (this.cnn == null)
                {
                    InternalOpen = true;
                    InicializarAdaptadores();
                }
                #endregion
                List<FACTURAS> list = new List<FACTURAS>();
                foreach (DataSet.V_FACTURASRow rw in vAdapterMaster.GetDataByNroFactura(nroFactura))
                {
                    list.Add(GetEntity(rw, null));
                }
                return list;
            }
            finally
            {
                if (InternalOpen && this.cnn.State != System.Data.ConnectionState.Closed)
                    this.cnn.Close();
            }
        }

        public List<FACTURAS> GetByFacturasPendientesPagos(decimal idCliente)
        {
            bool InternalOpen = false;
            try
            {
                #region Inicializar Metodo
                if (this.cnn == null)
                {
                    InternalOpen = true;
                    InicializarAdaptadores();
                }
                #endregion
                List<FACTURAS> list = new List<FACTURAS>();
                foreach (DataSet.V_FACTURASRow rw in vAdapterMaster.GetDataByFacturasPendientesPagos(idCliente))
                {
                    list.Add(GetEntity(rw, null));
                }
                return list;
            }
            finally
            {
                if (InternalOpen && this.cnn.State != System.Data.ConnectionState.Closed)
                    this.cnn.Close();
            }
        }

        private FACTURAS GetEntity(DataSet.V_FACTURASRow rwMaster, DataSet.V_FACTURAS_DETALLESDataTable tdDetaill)
        {
            FACTURAS factura = null;
            if (rwMaster != null)
            {
                factura = new FACTURAS();
                factura.ID = rwMaster.ID;
                factura.ID_CONDICION = rwMaster.ID_CONDICION;
                factura.CONDICIONES = new CONDICIONES { ID = rwMaster.ID_CONDICION, CONDICION = rwMaster.CONDICION };
                factura.ID_NCF = rwMaster.ID_NCF;
                factura.NCF = new NCF { ID = rwMaster.ID, DESCRIPCION = rwMaster.DESC_NCF, NCF1 = rwMaster.NCF };
                factura.ID_CLIENTE = rwMaster.ID_CLIENTE;
                factura.CLIENTES = new CLIENTES { ID = rwMaster.ID_CLIENTE, CLIENTE = rwMaster.CLIENTE };
                factura.ID_VENDEDOR = rwMaster.ID_VENDEDOR;
                factura.VENDEDORES = new VENDEDORES { ID = rwMaster.ID_VENDEDOR, VENDEDOR = rwMaster.VENDEDOR };
                factura.ID_USUARIO = rwMaster.ID_USUARIO;
                factura.USUARIOS = new USUARIOS { ID = rwMaster.ID_USUARIO, NOMBRE_USUARIO = rwMaster.USUARIO };
                factura.NRO_FACTURA = rwMaster.NRO_FACTURA;
                factura.SEQ_NCF = rwMaster.SEQ_NCF;
                factura.FECHA_HORA = rwMaster.FECHA_HORA;
                factura.FECHA_VENCIMIENTO = rwMaster.FECHA_VENCIMIENTO;
                if (!rwMaster.IsCOTIZACIONESNull())
                    factura.ID_COTIZACIONES = rwMaster.COTIZACIONES;
                if (!rwMaster.IsORDEN_COMPRANull())
                    factura.ORDEN_COMPRA = rwMaster.ORDEN_COMPRA;
                if (!rwMaster.IsOBSERVACIONESNull())
                    factura.OBSERVACIONES = rwMaster.OBSERVACIONES;
                factura.ACTIVO = rwMaster.ACTIVO;
                factura.T_DESCUENTO = rwMaster.T_DESCUENTO;
                factura.T_IMPUESTO = rwMaster.T_IMPUESTO;
                factura.M_TOTAL = rwMaster.M_TOTAL;
                factura.M_PAGADO = rwMaster.M_PAGADO;

                if (tdDetaill != null)
                {
                    factura.FACTURAS_PAGOS = new FacturasPagosDA().GetByIdFactura(rwMaster.ID);
                    foreach (DataSet.V_FACTURAS_DETALLESRow rw in tdDetaill)
                    {
                        if (rw != null)
                        {
                            FACTURAS_DETALLES facturadetalle = new FACTURAS_DETALLES();
                            facturadetalle.ID = rw.ID;
                            facturadetalle.ID_PRODUCTO = rw.ID_PRODUCTO;
                            facturadetalle.PRODUCTOS = new PRODUCTOS { ID = rw.ID_PRODUCTO, CODIGO = rw.CODIGO };
                            facturadetalle.MEDIDAS = new MEDIDAS { ID = rw.ID_MEDIDA, MEDIDA = rw.MEDIDA };
                            facturadetalle.DESCRIPCIONES = new DESCRIPCIONES { ID = rw.ID_DESCRIPCION, DESCRIPCION = rw.DESCRIPCION };
                            facturadetalle.CANTIDAD = rw.CANTIDAD;
                            facturadetalle.COSTO = rw.COSTO;
                            facturadetalle.PRECIO = rw.PRECIO;
                            facturadetalle.DESCUENTO = rw.DESCUENTO;
                            facturadetalle.X_DESCUENTO = rw.X_DESCUENTO;
                            facturadetalle.IMPUESTO = rw.IMPUESTO;
                            facturadetalle.X_IMPUESTO = rw.X_IMPUESTO;
                            facturadetalle.C_DEVUELTA = rw.C_DEVUELTA;
                            factura.FACTURAS_DETALLES.Add(facturadetalle);
                        }
                    }

                }
            }
            return factura;
        }

        public bool Anular(FACTURAS entity)
        {
            if (entity.ACTIVO)
            {
                bool InternalOpen = false;
                try
                {
                    #region Inicializar Metodo
                    if (this.cnn == null)
                    {
                        InternalOpen = true;
                        InicializarAdaptadores();
                    }
                    #endregion

                    entity = this.GetById(entity.ID);

                    //Validar si tiene pagos con notas de credito para reponer su monto
                    foreach (FACTURAS_PAGOS value in entity.FACTURAS_PAGOS)
                    {
                        if (value.ID_TIPO == 4)
                        {
                            string[] val = value.NRO_DOCUMENTO.Split('-');
                            this.AdapterNC.NcUpdateCommandM_Utilizado(value.MONTO * -1, decimal.Parse(val[0]));
                        }
                    }

                    this.entitiesDetaill = this.AdapterDetaill.GetDataByID(entity.ID);

                    foreach (DataSet.FACTURAS_DETALLESRow rw in this.entitiesDetaill)
                    {
                        this.AdapterProductos.ProductosUpdateExistencia(rw.CANTIDAD, rw.ID_PRODUCTO);
                    }

                    this.AdapterMaster.Connection = cnn;
                    this.AdapterMaster.Transaction = tr;

                    this.entityMaster = this.AdapterMaster.GetDataByID(entity.ID).FirstOrDefault();

                    this.entityMaster.ACTIVO = false;

                    this.AdapterMaster.Update(this.entityMaster);


                    if (entity.ID_CONDICION == 1)
                    {
                        DataSet.CLIENTESRow rwCliente = AdapterClientes.GetDataByID(entity.ID_CLIENTE).FirstOrDefault();
                        rwCliente.MONTO_ADEUDADO -= entity.M_TOTAL;
                        AdapterClientes.Update(rwCliente);
                    }
                    entity.ACTIVO = false;
                    tr.Commit();
                    return true;
                }
                finally
                {
                    if (InternalOpen && this.cnn.State != System.Data.ConnectionState.Closed)
                        this.cnn.Close();
                }
            }
            else
                return false;
        }

        public bool PagarFactura(List<FACTURAS_PAGOS> value)
        {
            bool InternalOpen = false;
            try
            {
                #region Inicializar Metodo
                if (this.cnn == null)
                {
                    InternalOpen = true;
                    InicializarAdaptadores();
                }
                #endregion

                #region Pagos
                //Insertar los pagos y ajustar montos pagados de la factura             
                decimal montoPagado = 0;
                if (value.Count > 0)
                {
                    this.entitiesFacturasPagos = new DataSet.FACTURAS_PAGOSDataTable();

                    foreach (FACTURAS_PAGOS rw in value)
                    {
                        montoPagado = montoPagado + rw.MONTO;
                        DataSet.FACTURAS_PAGOSRow rwPagos = this.entitiesFacturasPagos.NewFACTURAS_PAGOSRow();
                        rwPagos.ID_FACTURA = rw.ID_FACTURA;
                        rwPagos.ID_TIPO = rw.ID_TIPO;
                        if (rw.ID_BANCO != null && rw.ID_BANCO != 0)
                            rwPagos.ID_BANCO = (decimal)rw.ID_BANCO;
                        rwPagos.ID_USUARIO = rw.ID_USUARIO;
                        if (rw.NRO_DOCUMENTO != string.Empty)
                            rwPagos.NRO_DOCUMENTO = rw.NRO_DOCUMENTO;
                        if (rw.PORTADOR != string.Empty)
                            rwPagos.PORTADOR = rw.PORTADOR;
                        if (rw.TELEFONO != string.Empty)
                            rwPagos.TELEFONO = rw.TELEFONO;
                        rwPagos.FECHA = rw.FECHA;
                        rwPagos.MONTO = rw.MONTO;
                        entitiesFacturasPagos.AddFACTURAS_PAGOSRow(rwPagos);

                        //Si el pago es con nota de credito
                        if (rw.ID_TIPO == 4)
                        {
                            string[] val = rw.NRO_DOCUMENTO.Split('-');
                            this.AdapterNC.NcUpdateCommandM_Utilizado(rw.MONTO, decimal.Parse(val[0]));
                        }
                    }
                    this.AdapterFacturasPagos.Update(this.entitiesFacturasPagos);
                    this.entityMaster = this.AdapterMaster.GetDataByID(value.FirstOrDefault().ID_FACTURA).FirstOrDefault();
                    entityMaster.M_PAGADO = montoPagado;
                    AdapterMaster.Update(entityMaster);
                    this.tr.Commit();
                    return true;
                }
                return false;
                #endregion
            }
            catch
            {
                if (InternalOpen)
                    tr.Rollback();
                throw;
            }
            finally
            {
                if (InternalOpen && this.cnn.State != System.Data.ConnectionState.Closed)
                    this.cnn.Close();
            }
        }
    }
}
